package controller

import (
	"ai-curd/controller/request"
	"ai-curd/controller/response"
	"ai-curd/oo"
	"ai-curd/repository"
	"ai-curd/repository/ent"
	entuser "ai-curd/repository/ent/user"

	"github.com/gin-gonic/gin"
)

type User struct {
	repo *repository.User
}

func NewUser(repo *repository.User) *User {
	ctr := new(User)
	ctr.repo = repo
	return ctr
}

func (ctr *User) One(c *gin.Context) (response.Data, error) {
	req := new(request.UserOne)
	if err := c.ShouldBind(req); err != nil {
		return nil, err
	}

	ooUser := ctr.repo.Fetch(c.Request.Context(), req.ID)

	if ooUser == nil {
		return nil, nil
	}

	return ooUser.Mapper(), nil
}

func (ctr *User) Many(c *gin.Context) (response.Data, error) {
	req := new(request.UserMany)
	if err := c.ShouldBind(req); err != nil {
		return nil, err
	}

	ooUsers := ctr.repo.FetchMany(c.Request.Context(), func(query *ent.UserQuery) {
		query.Where(entuser.Category(req.Category))
	})
	return ooUsers.Mapper(), nil
}

func (ctr *User) Create(c *gin.Context) (response.Data, error) {
	req := new(request.UserCreate)
	if err := c.ShouldBind(req); err != nil {
		return nil, err
	}

	cmdUser := oo.NewUser(req.Category)
	cmdUser.SetCategory(req.Category)
	cmdUser.SetPhone(req.Phone)
	cmdUser.SetNickname(req.Nickname)

	ooUser := ctr.repo.Save(c.Request.Context(), cmdUser)
	return ooUser.Mapper(), nil
}

func (ctr *User) Modify(c *gin.Context) (response.Data, error) {
	req := new(request.UserModify)
	if err := c.ShouldBind(req); err != nil {
		return nil, err
	}

	cmdUser := oo.NewUser(req.Category)
	cmdUser.SetID(req.ID)
	cmdUser.SetCategory(req.Category)
	cmdUser.SetPhone(req.Phone)
	cmdUser.SetNickname(req.Nickname)

	return ctr.repo.Modify(c.Request.Context(), cmdUser), nil
}

func (ctr *User) Delete(c *gin.Context) (response.Data, error) {
	req := new(request.UserOne)
	if err := c.ShouldBind(req); err != nil {
		return nil, err
	}

	return ctr.repo.Delete(c.Request.Context(), func(query *ent.UserDelete) {
		query.Where(entuser.ID(req.ID))
	}), nil
}
